\chapter{Implementation}
%In this chapter we will look into how we have implemented the necessary components and what role they play to the system.

As part of this topic we were to make a multi-tier architecture which means it contains multiple layers. As seen in \figref{fig:Architecture} we have clients at the front-end connected through a webservice/WCF to a server which in the business layer validates the objects sent, to check if they comply with the business logic that has been implemented. It is then sent to the data access layer which then contacts the database that depending on the request reads or writes and then sends back the requested data.

This chapter will explain how we have implemented the different tiers and what role they have in the system, what they do and how they work as a whole.
% Evt. skriv om arkitektur + billed...

\begin{figure}[H]
\includegraphics[width=1\linewidth]{img/SystemDesignN.png}
\caption{Sample figure of a Multi-Tier Architecture}
\label{fig:Architecture}
\end{figure}


\section{Server}
Our server acts as the "Man in the Middle". The server receives requests from the clients through WCF and contacts the business layer and afterwards the database, and lastly sends answer back to the client. The choice of implementing the server this way is to establish a connection between the server and the clients which makes the server handle all the logic and database access. The advantages of this is that we will have all the base functionality on the server, which also increases the security since the clients can't be altered and access the database to perform any harm, or in any other way be changed to exploit possible bugs, as easy as if all the functionality was freely accessible. The server can furthermore be optimized to run multithreaded, which will increase the speed per CPU core available.


\section{Client} 
The clients will cover over multiple parts. The website where the customer can choose what to see and where to sit. The administrative part for the staff in the cinema which could include additional features, like adding movies, change schedules and other tasks which should only be available for the staff. Another possible client could be a third-party client which could use an application programming interface (API) where they could make their own clients. However, we will not have this included in our first release as this would need to include additional security as third-parties may use APIs in harmful ways.


\subsection{Website}
We have made a website that can be used by customers to make a reservation to a show. The website is written in ASP.NET and offers the basic functionality to perform a use case scenario. The website will be connected to our system and interact with the server as any other client would through a webservice.

\subsection{Administrative Client}
The Administrative Client is meant to be a client the staff can use. It will have the same functionality as the web client using the website, but could also implement functionality to add or remove movies and choose in which hall the movie will be shown as this could be an important feature for the staff to have.


\section{Business Layer}
The business layer takes care of all business logic and modeling we have defined. It gets information from the WCF and uses the control layer to determine if an object is valid before sending the objects to the database.

\subsection{Model Layer}
The model layer contains all the main object, such as movie, seat, user, etc. These are the main components defined in our domain model. It is in the system to handle objects.

\subsection{Controller Layer}
The controller layer's job is to check if the entered data is valid according to our business logic, before any objects are sent to the database controller. If the entered data is invalid, a fault exception is thrown which the client then needs to handle.  

\subsection{Database Connector}
The database connector creates the connection to the database, which makes it possible for the system to make changes in the database. We have used parameterized query as this makes is impossible to write structured query language (SQL) code that prevent injections and there by adding security for the database connections. For a future implementation it would be a great opportunity to support more than one database, e.g. if the company wants to expand and build more cinemas, or would have multiple databases with different SQL.

\section{Seat Selection Algorithm}
It is nearly impossible to define where the "best seat" is, because it is a matter of personal preference. We could define where the best seat would be from what experts say about how far you should be from the screen\cite{Theater}, but we think the best place to sit is in the center of the cinema hall. We have implemented a prototype algorithm, which will choose a seat as close to the center as possible, using the formula \ref{eq:distanceformular} to find the distance between two points\cite{Vector2}.

\begin{equation}
d=\sqrt{(y2 - y1)^2 + (x2 - x1)^2}
\label{eq:distanceformular}
\end{equation}

We did however find it to select seats in some very circular patterns, instead of choosing multiple seats in the same row. We have added some constants to change the behavior and selections. Formula \ref{eq:OurFormular} is how we implemented it in our system. This formula will select more seats on a middle row before moving a row up or down. $C1$ is an offset on the Y axis that shifts the middle point up or down in the grid and $C2$ is a weight to "add" distance each time you move up or down on the Y axis, e.g. if $C2$ is equal to 2 the actual calculated distance would be the double on the Y axis compared to the X axis, or the distance to the seat next to you is half the distance of the seat in front of you.

\begin{equation}
d=\sqrt{(y2 - y1 + C1)^2 * C2 + (x2 - x1)^2}
\label{eq:OurFormular}
\end{equation}

Below we have an example on the implementation of the method to find the best seat as it is set up in the administrative client. We have implemented this method slightly different on the ASP.NET page. First a check is made to see if there are more seats selected than the amount. Then it finds and removes the first added entry. Lastly, it loops over every single seat and returns the amount of seats requested.

\begin{lstlisting}
public void FindBestSeats(int amount)
{
    if (CurrentHall == null)
        return;
    if (amount < selected.Count)
    {
        for (int i = 0; i < selected.Count - amount; i++)
        {
            int x = CurrentHall.Rows.IndexOf(CurrentHall.Rows.First(r => r.Seats.Any(s => s.ID == selected[0].ID)));
            int y = CurrentHall.Rows[x].Seats.IndexOf(CurrentHall.Rows[x].Seats.First(s => s.ID == selected[0].ID));
            //Updates gui
            CurrentHall.Rows[x].Seats[y].Occupied = false;
            selected.RemoveAt(0);
        }
        return;
    }
            
    SeatLimit = amount;
    int Rows = CurrentHall.Rows.Count - 1;
    int Cols = CurrentHall.Rows.Max(s => s.Seats.Count) - 1;
    Point Center = new Point(Rows / 2, Cols / 2);

    List<Point> bestpoint = new List<Point>();

    for (int r = 0; r < Rows + 1; r++)
    {
        for (int c = 0; c < Cols + 1; c++)
        {
            if (CurrentHall.Rows[r].Seats[c].Occupied)
            {
                continue;
            }
            if (bestpoint.Any(s => Distance(Center, s) >= Distance(Center, new PointF(r, c))) || bestpoint.Count == 0)
            {
                bestpoint.Add(new Point(r, c));
                        
                if (bestpoint.Count > (amount - selected.Count))
                {
                    bestpoint = bestpoint.OrderByDescending(d => Distance(d, Center)).ToList<Point>();
                    bestpoint.RemoveAt(0);
                }
            }
        }
    }
    foreach (Point p in bestpoint)
    {
    	//Do something with the point/find the seats + update GUI
    }
    //translate the points to seat locations and add tickets to the reservation
}

public static double Distance(PointF p1, PointF p2)
{
	return Math.Sqrt(Math.Pow((p1.X - p2.X + 2) * 6, 2) + Math.Pow((p1.Y - p2.Y), 2));
}
\end{lstlisting}